import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * @author Anna-Katharina Wickert 
 * @author Yannic Remmet
 * @author Tobias Trabelsi
 * 
 * @version 0.8.1
 * @since 22.06.2012
 *
 * @license Beer-Ware License (Revision 42)
 *
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * We wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy us a beer in return.
 * ----------------------------------------------------------------------------
 */
/**
 * 
 * @author yannicremmet
 *
 *	Controlls for the Game of Life
 */
public class Controlls {
	int width = 150;
	int height = 75;
	Logic log;
	ObserverComponent grid;
	JComboBox<String> pattern;
	boolean run;
	public boolean getRun() {
		return run;
	}
	Controlls(){
		final JFrame mainFrame = new JFrame("Game of Life");
		mainFrame.setLayout(new BorderLayout());
		
		GridBagLayout gbl = new GridBagLayout();
		//mainFrame.setLayout(gbl);
		
		log = new Logic(width,height);
		grid = new ObserverComponent(log);
		log.setC(this);
		
		log.addObserver(grid);
		
		
		JPanel p = new JPanel();
		p.setLayout(gbl);
		
		JButton start = new JButton("Start");
		start.setToolTipText("Start Life");
		JButton stop = new JButton("Stop");
		stop.setToolTipText("Ich hab keinen schimmer wie ich den kack implementieren soll. So ne kacke :(");
		JButton clear = new JButton("Clear");
		clear.setToolTipText("Kills all living cells");
		pattern = new JComboBox<String>(log.pattern);
		
		String[] n =  {"Auto","50","75","100","150","200","300","500","1000" };
		final JComboBox<String> gens = new JComboBox<String>(n);
		gens.setToolTipText("Auto stops if nothing changes \n" +
							"Or we trepassing the fieldd \n" +
							"WARNING MIGHT BE ENDLESS");
		
		gens.setEditable(true);
		Integer[] f = {100, 150, 200 , 300 , 400, 500, 1000};
		final JComboBox<Integer> speed = new  JComboBox<Integer>(f);	
		
		addComp(p, gbl, new JLabel(),			   1, 1, 1, 1, 5, 1);
		addComp(p, gbl, new JLabel("Start Life"),  2, 1, 1, 1, 1, 1);
		addComp(p, gbl, start,        			   3, 1, 1, 1, 1, 1);
		addComp(p, gbl, stop,    			       4, 1, 1, 1, 1, 1);
		addComp(p,gbl,pattern, 					   5, 1, 1, 1, 1, 1);
		addComp(p, gbl, clear, 					   7, 1, 1, 1, 1, 1);
		addComp(p, gbl, new JLabel(),			  15, 1, 1, 1, 5, 1);
		addComp(p, gbl, new JLabel(),			   1, 5, 1, 1, 5, 1);
		addComp(p, gbl, new JLabel("Speed"), 	   2, 5, 1, 1, 1, 1);
		addComp(p, gbl, speed,         			   3, 5, 1, 1, 1, 1);
		addComp(p, gbl, new JLabel("Generations"), 4, 5, 1, 1, 1, 1);
		addComp(p, gbl, gens,                      5, 5, 1, 1, 1, 1);
		addComp(p, gbl, new JLabel(), 			   6, 5, 1, 1, 5, 1);
		
		stop.setEnabled(false);

		//addComp(mainFrame, gbl, grid, 1, 1, 5, 5, 5, 5);
		//addComp(mainFrame, gbl, p, 1, 2, 1, 2, 1, 1);
		mainFrame.add(grid, BorderLayout.CENTER);
		mainFrame.add(p,BorderLayout.SOUTH);
		mainFrame.setSize(751,430);

		mainFrame.setVisible(true);

		start.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				run = true;
				Object g = gens.getSelectedItem();
				Object s = speed.getSelectedItem();
				int spe = (s instanceof Integer) ? (Integer)s  : 0 ;
				int gen ;//(g instanceof Integer) ? (Integer)g  : 0 ;
				if (gens.getSelectedIndex() != 0)
					gen = Integer.parseInt((g instanceof String) ? (String)g: "0");
				else 
					gen = 0;
				
				if(gen == 0){
					while(run && log.nextGeneration()){
						try {
							Thread.sleep(spe);
						} catch (InterruptedException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					}
				}
				else{
				for (int i = 0; run && i < gen && log.nextGeneration(); i++){
					try {
						Thread.sleep(spe);
						System.out.println(i);

					} catch (InterruptedException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				}
			}
		});
		clear.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				log.clear();
			}
		});
		grid.addMouseMotionListener(new MouseAdapter() {
			int oldI;
			int oldJ;
			
			public void mouseDragged(MouseEvent e) {
				int i = e.getPoint().x * log.getWidth() / grid.getWidth();
				int j = e.getPoint().y * log.getHeight() / grid.getHeight();
				
				if (pattern.getSelectedIndex() == 0){
					if ((i != oldI || j != oldJ) && i>-1 && i<log.getWidth() && j>-1 && j<log.getHeight()){	
						oldI=i;
						oldJ=j;
						log.cellChangeState(i,j);
					}
				}
				else{
					log.pattern(pattern.getSelectedIndex(), i, j);
				}	
				
			}
				
		});
		
		mainFrame.addWindowListener(new WindowAdapter() {
			
			
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		grid.addMouseListener(new MouseAdapter() {
		
			
			public void mouseClicked(MouseEvent e) {
				int i = e.getPoint().x * log.getWidth() / grid.getWidth();
				int j = e.getPoint().y * log.getHeight() / grid.getHeight();

				if (pattern.getSelectedIndex() == 0){
					if (i>-1 && i<log.getWidth() && j>-1 && j<log.getHeight()){	
	
						log.cellChangeState(i,j);
					}
				}
				else{
					log.pattern(pattern.getSelectedIndex(), i, j);
				}	
				
			}
		});
	}
	
	public static void main (String[] args){
		new Controlls();
	}
	
	

	
	/**
	 * This method makes it easier to add item by using the GridBagLayout
	 * 
	 * 
	 * @param co		Container
	 * @param gbl		Used GridBagLayout
	 * @param c			Item which should be added to the Container
	 * @param x			Row of the Item
	 * @param y			Line of the Item
	 * @param width		Width of the Item in Grids
	 * @param height	Height oh the Item in Grids
	 * @param wx		"Weight" oh the Item on the x-axis
	 * @param wy		"Weight" of the Item on the y-axis 
	 */
	
	private static void addComp(Container co, GridBagLayout gbl, JComponent c, int x,
			int y, int width, int height, double wx, double wy) {
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.BOTH;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.weightx = x;
		gbc.weighty = y;
		gbc.gridwidth = width;
		gbc.gridheight = height;
		gbc.weightx = wx;
		gbc.weighty = wy;
		gbl.setConstraints(c, gbc);
		co.add(c);
	}
}
